﻿using CodeGeneratorBootstrap.Models;
using CodeGeneratorBootstrap.ProjectServices;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using TemplateManager;

namespace CodeGeneratorBootstrap.Generators
{
    internal class MVC3Generator : Generator
    {
        public override void Generate(int projectId, string outputPath)
        {
            Console.WriteLine("Started  : " + DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff"));

            MetaData model = new MetaData();
            model.Models = this.GetClassesByProjectId(projectId);
            model.Project = this.GetProjectByProjectId(projectId);

            Console.WriteLine("Finished : " + DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff"));

            //if (Console.ReadKey().Equals(ConsoleKey.Escape))
            //{
                List<LookupClassModel> list = this.GetLookupClass(model.Models);

                MVC3DALGenerator dal = new MVC3DALGenerator();
                dal.Generate(model, list, outputPath);

                MVC3BLGenerator bl = new MVC3BLGenerator();
                bl.Generate(model, list, outputPath);

                MVC3WebGenerator web = new MVC3WebGenerator();
                web.Generate(model, list, outputPath);

                //classmodel Rbac
                List<ClassModel> listclassrbac = this.GetClassesByProjectIdRbac(projectId);
 
                if (model.Project.RBAC)
                {

                    GenerateSolutionRbac(projectId, outputPath, listclassrbac);
                }
                else
                {
                    GenerateSolution(projectId, outputPath);
                }
            //}
        }

        private IProject GenerateSolution(int projectId, string outputPath)
        {
            ProjectBLClient client = new ProjectBLClient();
            ProjectDto project = client.GetProject(new ProjectPkDto() { ProjectId = projectId }).Data;

            string projectName = project.Name;
            string solutionName = projectName;
            string mvcProjectName = projectName + ".Web";
            string blProjectName = projectName + ".Service";
            string dalProjectName = projectName + ".DAL";
            string templateDirectory = @"C:\test\Template\ComplexWebApplication1Rbac\";
            string primaryOutputDirectory = outputPath + @"\" + projectName + @"\";
            string completeProjectDirectory = outputPath + @"\Complete\";

            ComplexTemplate t = new ComplexTemplate();
            t.ProjectPath = templateDirectory;
            IProject p = t.CreateNewProject(solutionName, completeProjectDirectory,
                                            dalProjectName, blProjectName, mvcProjectName);
            p.AddFile(primaryOutputDirectory);
            return p;
        }

        private IProject GenerateSolutionRbac(int projectId, string outputPath, List<ClassModel> list)
        {
            ProjectBLClient client = new ProjectBLClient();
            ProjectDto project = client.GetProject(new ProjectPkDto() { ProjectId = projectId }).Data;

            //write class ProjectModel Rbac
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("else if (projectId == {0})", projectId);
            sb.AppendLine("{");
            sb.AppendLine(Environment.NewLine);
            foreach (var classname in list)
            {
                sb.AppendFormat("result.Add(\"{0}\");", classname.Name);
                sb.AppendLine(Environment.NewLine);
            }
            sb.AppendLine("}");

            string projectName = project.Name;
            string solutionName = projectName;
            string mvcProjectName = projectName + ".Web";
            string blProjectName = projectName + ".Service";
            string dalProjectName = projectName + ".DAL";
            string templateDirectory = @"C:\test\Template\ComplexWebApplicationRbac\";
            string primaryOutputDirectory = outputPath + @"\" + projectName + @"\";
            string completeProjectDirectory = outputPath + @"\Complete\";
            string completeProjectDirectoryRbac = outputPath + @"\Complete\" + projectName + @"\RbacLib\";
            ComplexTemplate t = new ComplexTemplate();
            t.ProjectPath = templateDirectory;
            IProject p = t.CreateNewProject(solutionName, completeProjectDirectory,
                                            dalProjectName, blProjectName, mvcProjectName);
            p.AddFile(primaryOutputDirectory);

            
            //Rbac back-end Directory Template
            string RbacManagement = @"C:\test\Template\RBAC\";
            string RbacManagementComplete = completeProjectDirectory + @"\RBAC\";
            //copy RbacLib
            string templateDirectoryRbac = @"C:\test\Template\ComplexWebApplicationRbac\RbacLib\";
            //copy Rbac back-end
            DirectoryCopy(RbacManagement, RbacManagementComplete, true);
            
            DirectoryCopy(templateDirectoryRbac, completeProjectDirectoryRbac, true);
            string writefilename = completeProjectDirectoryRbac + @"Models\ProjectModel.cs";
            string text = File.ReadAllText(writefilename);
            text = text.Replace("/*@insert_class*/", sb.ToString());
            File.WriteAllText(writefilename, text);

            return p;
        }

        public void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
        {
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);
            DirectoryInfo[] dirs = dir.GetDirectories();

            // If the source directory does not exist, throw an exception.
            if (!dir.Exists)
            {
                throw new DirectoryNotFoundException(
                    "Source directory does not exist or could not be found: "
                    + sourceDirName);
            }

            // If the destination directory does not exist, create it.
            if (!Directory.Exists(destDirName))
            {
                Directory.CreateDirectory(destDirName);
            }


            // Get the file contents of the directory to copy.
            FileInfo[] files = dir.GetFiles();

            foreach (FileInfo file in files)
            {
                // Create the path to the new copy of the file.
                string temppath = Path.Combine(destDirName, file.Name);

                // Copy the file.
                file.CopyTo(temppath, false);
            }

            // If copySubDirs is true, copy the subdirectories.
            if (copySubDirs)
            {

                foreach (DirectoryInfo subdir in dirs)
                {
                    // Create the subdirectory.
                    string temppath = Path.Combine(destDirName, subdir.Name);

                    // Copy the subdirectories.
                    DirectoryCopy(subdir.FullName, temppath, copySubDirs);
                }
            }
        }



    }
}
